package com.huayi.datagovernance.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.huayi.datagovernance.common.SysConstant;
import com.huayi.datagovernance.dao.master.DeviceDao;
import com.huayi.datagovernance.dao.master.TYDao;
import com.huayi.datagovernance.dao.slave.LxTaskDao;
import com.huayi.datagovernance.dao.yx.YxBaseDao;
import com.huayi.datagovernance.entity.*;
import com.huayi.datagovernance.exception.BizException;
import com.huayi.datagovernance.service.LxTaskService;
import com.huayi.datagovernance.service.TYwTaskService;
import com.huayi.datagovernance.service.TYwTaskYkService;
import com.huayi.datagovernance.service.TYwTqlbService;
import com.huayi.datagovernance.vo.ResponseResult;
import common.parent.system.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

import static com.huayi.datagovernance.utils.RestTemplateUtils.restTemplate;

/**
 * 朗新工单 服务实现类
 * @author wuch
 * @version 1.0
 * @date 2021/4/24 11:53
 */
@Service
@Slf4j
public class LxTaskServiceImpl implements LxTaskService {

    @Resource
    private LxTaskDao lxTaskDao;

    @Resource
    private DeviceDao deviceDao;

    @Resource
    private TYwTaskService taskService;

    @Resource
    private TYwTqlbService tqlbService;

    @Resource
    private TYwTaskYkService taskYkService;

    @Resource
    private TYDao tyDao;

    @Resource
    private YxBaseDao yxBaseDao;

    @Override
    public List<TzyAppList> getTzyAppList() {
        return lxTaskDao.getTzyAppList();
    }

    @Override
    @DSTransactional
//    @Transactional(propagation= Propagation.NESTED, isolation= Isolation.READ_COMMITTED)
    public int saveTzyAppList(List<TzyAppList> tzyAppList) {
        try {
            //查询旧的数据
            QueryWrapper<TYwTask> wrapper = new QueryWrapper<>();
            wrapper.eq("gdtype", 3);
            List<TYwTask> taskListOld = taskService.list(wrapper);
            //旧数据为空，直接提交，否则判断是否重复
            if (taskListOld == null || taskListOld.size() == 0) {
                //保存数据
                return saveYkTask(tzyAppList);
            }
            //新下发的工单集合
            List<TzyAppList> newTzyAppList = new ArrayList<>();
            //遍历
            for (TzyAppList app : tzyAppList) {
                boolean isExists = false;
                //旧数据查找，有则跳过
                for (TYwTask taskOld : taskListOld) {
                    if(StrUtil.isEmpty(taskOld.getTaskid())) {
                        //工单号为空跳过
                        continue;
                    }
                    if (taskOld.getTaskid().equals(app.getAppNo())){
                        //工单号相同，证明已下发过
                        isExists = true;
                        break;
                    }
                }
                if (!isExists){//不存在，则添加
                    newTzyAppList.add(app);
                }
            }
            //保存数据
            return saveYkTask(newTzyAppList);
        } catch (Exception e) {
            log.info("saveTzyAppList执行异常，数据回滚",e);
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return 0;
        }
    }

    /**
     * 保存业扩工单
     * @param newTzyAppList 业扩工单
     * @return
     */
    private int saveYkTask(List<TzyAppList> newTzyAppList) {
//        log.info("============保存业扩工单==============");
        List<String> sbids = new ArrayList<>();//线路id
        for (TzyAppList tzyApp : newTzyAppList) {
            //根据业扩工单构建Task任务
            TYwTask taskDTO = this.generateTaskFromYk(tzyApp);
            //根据Task任务构建Tqlb信息
            TYwTqlb tqlbDTO = this.generateTqlbFromTask(taskDTO);
            //构建工单下变压器清单
            List<TzyAppEquipRela> byqList = tzyApp.getEquipRelas();
            if (byqList != null && byqList.size() > 0) {
                List<TYwTaskYk> taskYkDTOS = new ArrayList<>(byqList.size());
                for (TzyAppEquipRela equipRela : byqList) {
                    TYwTaskYk taskYkDTO = new TYwTaskYk();
                    BeanUtils.copyProperties(equipRela,taskYkDTO);
                    taskYkDTO.setTaskid(taskDTO.getTaskid());//工单号 app_no
                    taskYkDTO.setSbid(String.valueOf(equipRela.getEquipId()));
                    taskYkDTO.setSbmc(equipRela.getTranName());
                    taskYkDTO.setDydj(equipRela.getFrstsideVoltCode());
                    taskYkDTO.setTqId(equipRela.getTgId());
                    taskYkDTO.setSsxl(equipRela.getLineId());
                    taskYkDTO.setSsdz(equipRela.getSubsId());
                    taskYkDTOS.add(taskYkDTO);
                }
                //保存变压器
                taskYkService.saveBatch(taskYkDTOS);
                //设置线路id 转成营销库的pms_line_id
                long lineId = byqList.get(0).getLineId();
                String pmsLineId = yxBaseDao.getPmsLineId(lineId);
                taskDTO.setSsxl(StringUtils.isEmpty(pmsLineId)? String.valueOf(lineId) : pmsLineId);
//                taskDTO.setSsxl(byqList.get(0).getLineId());
                tqlbDTO.setTqsbid(taskDTO.getSsxl());
//                tqlbDTO.setTqmodelid(taskDTO.getSsxl());
//                tqlbDTO.setModelname(taskDTO.getSsxl());
                sbids.add(taskDTO.getSsxl());//添加需要下发图形的线路
//                log.info("保存变压器清单成功");
            }
            //保存任务
            taskService.save(taskDTO);
//            log.info("保存TASK成功");
            tqlbService.save(tqlbDTO);
//            log.info("保存TQLB成功");
        }
        //调用远程服务，下发工单出图信息
        if (sbids.size()>0){
            this.noticeSendOutPic(sbids, SysConstant.XL_SBZLX);
        }
        return newTzyAppList.size();
    }

    /**
     * 根据Task任务构建Tqlb任务
     */
    private TYwTqlb generateTqlbFromTask(TYwTask taskDTO) {
        TYwTqlb tqlb = new TYwTqlb();
        //获取新的oid
        long oid = tyDao.getUUOID("'ywsj.seq_t_yw_tqlb_oid'");
        tqlb.setOid((int) oid)
                .setSfzj(0)
                .setGdtype(taskDTO.getGdtype())
                .setStatus(0)
                .setCreateTime(new Date())
                .setTqsbid(taskDTO.getSsxl())
//                .setTqmodelid(taskDTO.getSsxl())
//                 .setModelname(taskDTO.getSsxl())
                .setTaskid(taskDTO.getOid());
        return tqlb;
    }

    /**
     * 根据业扩工单构建Task任务
     */
    private TYwTask generateTaskFromYk(TzyAppList tzyApp) {
        TYwTask task = new TYwTask();
        //获取新的oid
        long oid = tyDao.getUUOID("'ywsj.seq_t_yw_task_oid'");
        //获取新的versionid
        long versionId = tyDao.getUUOID("'scyw.seq_conf_version_oid'");
        task.setOid(oid)
                .setVersionid((int) versionId)
//                .setTaskid(String.valueOf(tzyApp.getAppId()))//业扩工单号
                .setTaskid(tzyApp.getAppNo())//业扩工单号
                .setGdtype(Integer.valueOf(SysConstant.TASK_STATE_YK))// 1为专线，台区为2
                .setName(tzyApp.getAppNo())// 业扩工单 - 工单号
                .setDatafrom(3)//1-手动创建 2-7009系统 3--图形质检 4--朗新推送
                .setSfdszj(0)
                .setSfts(1)
                .setCreateTime(new Date())
                .setYxdw(tzyApp.getConsName())// 用户名称
                .setXgsmc(tzyApp.getElecAddr()) // 用电地址
                .setTasktime(new Date());
        return task;
    }

    @Override
    public List<HighCheckApp> getHighCheckList() {
        return lxTaskDao.getHighCheckList();
    }

    @Override
    @DSTransactional
    public int saveHighCheckList(List<HighCheckApp> highCheckApps) {
        try {
//            log.info("============保存高压核查工单============");
            //查询旧的数据
            QueryWrapper<TYwTask> wrapper = new QueryWrapper<>();
            wrapper.eq("gdtype", 4);
            List<TYwTask> taskListOld = taskService.list(wrapper);
            //旧数据为空，直接提交，否则判断是否重复
            if (taskListOld == null || taskListOld.size() == 0) {
                //保存数据
                return saveHighCheckTask(highCheckApps);
            }
            //新下发的工单集合
            List<HighCheckApp> newHighCheckApp = new ArrayList<>();
            //遍历
            for (HighCheckApp app : highCheckApps) {
                boolean isExists = false;
                //旧数据查找，有则跳过
                for (TYwTask taskOld : taskListOld) {
                    if (StrUtil.isEmpty(taskOld.getTaskid())) continue;;
                    if (taskOld.getTaskid().equals(app.getAppNo())){
                        isExists = true;
                        break;
                    }
                }
                if (!isExists){//不存在，则添加
                    newHighCheckApp.add(app);
                }
            }
            //保存数据
            return saveHighCheckTask(newHighCheckApp);
        } catch (Exception e) {
            log.warn("saveHighCheckList执行异常，数据回滚",e);
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return 0;
        }
    }

    /**
     * 保存高压核查工单
     * @param highCheckApps
     * @return
     */
    private int saveHighCheckTask(List<HighCheckApp> highCheckApps) {
//        log.info("========保存高压核查工单=========");
        List<String> sbids = new ArrayList<>();//线路id
        for (HighCheckApp checkApp : highCheckApps) {
            //根据高压核查工单构建Task任务
            TYwTask taskDTO = this.generateTaskFromHighCheck(checkApp);
            //根据高压核查工单构建Tqlb信息
            TYwTqlb tqlbDTO = this.generateTqlbFromTask(taskDTO);
            tqlbDTO.setModelname(checkApp.getLineName());
            //保存高压核查变压器信息
            List<HighCheckTran> byqList = checkApp.getTranList();
            if (byqList != null && byqList.size() > 0) {
                List<TYwTaskYk>  taskYkDTOS = new ArrayList<>(byqList.size());
                for (HighCheckTran checkTran : byqList) {
                    TYwTaskYk taskYkDTO = new TYwTaskYk();
                    // BeanUtils.copyProperties(checkTran,taskYkDTO);
                    taskYkDTO.setSchemaId(IdUtil.getSnowflake(1, 1).nextId())
                            .setTaskid(taskDTO.getTaskid())//工单号
                            .setSbid(checkTran.getEquipId())//变压器id
                            .setSbmc(checkTran.getTranName())//变压器名称
                            .setTqId(StrUtil.isNotEmpty(checkTran.getTgId()) ? Long.parseLong(checkTran.getTgId()):0)//台区id
                            .setSsxl(StrUtil.isNotEmpty(checkTran.getLineId()) ? Long.parseLong(checkTran.getLineId()):0)//线路id
                            .setSuperId(checkTran.getRealTgId())//实际变压器id
                            .setSuperName(checkTran.getRealTgName());//实际变压器名称
                    taskYkDTOS.add(taskYkDTO);
                }
                //保存变压器
                taskYkService.saveBatch(taskYkDTOS);
//                createDao.addHighCheckByqBatch(taskYkDTOS);
//                log.info("保存变压器清单成功");
            }
            //保存线路信息
            // createDao.addHighCheckLine(taskYkDTO);
            // log.info("保存高压核查线路信息成功");
            //保存任务
            taskService.save(taskDTO);
//            log.info("保存TASK成功");
            tqlbService.save(tqlbDTO);
//            log.info("保存TQLB成功");
            sbids.add(taskDTO.getSsxl());
        }
        //调用远程服务，下发工单出图信息
        if (sbids.size()>0){
            this.noticeSendOutPic(sbids,SysConstant.XL_SBZLX);
        }
        return highCheckApps.size();
    }



    /**
     * 根据高压核查工单构建Task任务
     * @param checkApp
     * @return
     */
    private TYwTask generateTaskFromHighCheck(HighCheckApp checkApp) {
        TYwTask task = new TYwTask();
        //获取新的oid
        long oid = tyDao.getUUOID("'ywsj.seq_t_yw_task_oid'");
        //获取新的versionid
        long versionId = tyDao.getUUOID("'scyw.seq_conf_version_oid'");
        //设置线路id 转成营销库的pms_line_id
        String lineId = checkApp.getLineId();
        String pmsLineId = yxBaseDao.getPmsLineId(Long.valueOf(lineId));
        task.setOid(oid)
                .setVersionid((int) versionId)
                .setTaskid(checkApp.getAppNo())//高压核查工单号
                .setOrgno(checkApp.getOrgNo())
                .setGdtype(Integer.valueOf(SysConstant.TASK_STATE_HIGH_CHECK))// 1为专线，台区为2
                .setName(checkApp.getLineName())// 高压工单 - 线路名 lineName
                .setDatafrom(3)//1-手动创建 2-7009系统 3--图形质检 4--朗新推送
                .setSfdszj(0)
                .setSfts(1)
                .setCreateTime(new Date())
                .setSsxl(StringUtils.isEmpty(pmsLineId)? lineId : pmsLineId)
//                .setYxdw(tzyApp.getConsName())// 用户名称
//                .setSszrq(tzyApp.getElecAddr()) // 用电地址
                .setTasktime(new Date());
        return task;
    }


    @Override
//    @DSTransactional
    public int fetchWorkOrderFromLx(String gdtype) {
        int count = 0;
        if (gdtype.equals(SysConstant.TASK_STATE_YK)){
//            log.info("===============开始执行高压业扩工单流程===============");
            List<TzyAppList> tzyAppList = this.getTzyAppList();
            //测试用
            if (tzyAppList !=null && tzyAppList.size()>0){
//                log.info("业扩工单数据：{}"+ JSONObject.toJSONString(tzyAppList));
                count = this.saveTzyAppList(tzyAppList);
            }
            log.info("拉取高压业扩工单："+ count);

        }else {
//            log.info("===============开始执行高压核查工单流程===============");
            List<HighCheckApp> highCheckList = this.getHighCheckList();
            if (highCheckList !=null && highCheckList.size()>0){
                count = this.saveHighCheckList(highCheckList);
            }
            log.info("拉取高压核查工单数："+count);
        }
        return count;
    }

    @Override
    @Async("asyncTaskExecutor")
    @Transactional(rollbackFor = Exception.class)
    public void updateYkByqInfo(List<TYwTaskYk> byqList) {
        try {
            if (byqList != null && byqList.size()>0){
                System.out.println(Thread.currentThread().getName()+"执行异步回写变压器信息...");
                // log.info("回写变压器信息到朗新数据库");
                byqList.forEach((e)->{
                    lxTaskDao.updateYkOrderByq(e);
                    log.info("回写业扩变压器到朗新成功");
                });
            }
        } catch (Exception e) {
            log.error("回写业扩变压器到朗新成功失败",e);
            throw new BizException("回写业扩变压器到朗新失败");
        }
    }

    @Override
    @Async("asyncTaskExecutor")
    @Transactional(rollbackFor = Exception.class)
    public void updateHighCheckStatus(String taskId, String status, List<TYwTaskYk> byqList) {
        try {
            if (StrUtil.isEmpty(taskId) || StrUtil.isEmpty(status)){
                throw new BusinessException("高压核查单号和状态不能为空");
            }
            //修改变压器经纬
            byqList.forEach(byq->{
                lxTaskDao.updateHighCheckByq(byq);
                log.info("回写高压核查变压器到朗新成功");
            });
            //修改工单表状态
            lxTaskDao.updateHighCheckStatus(taskId, status);
            log.info("回写高压核查工单状态到朗新成功");
        } catch (BusinessException e) {
            log.error("回写高压核查信息到朗新失败",e);
            throw new BizException("回写高压核查信息到朗新失败");
        }
    }
    @Override
    public ResponseResult noticeSendOutPic(List<String> sbids, Integer sbzlx) {
        try {
            log.info("===============开始通知web端下发工单图形===============");
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON_UTF8);//json方式提交
            Map<String, Object> map= new HashMap<>();
            //营销线路sbid转gis的sbid
/*            List<Long> paramIds = new ArrayList<>();
            for (String id : sbids) {
                paramIds.add(Long.valueOf(id));
            }
            sbids = yxBaseDao.getPmsLineIdBatch(paramIds);*/
            map.put("sbids", sbids);
//            map.add("sbzlx", sbzlx);
            HttpEntity<Map<String, Object>> request = new HttpEntity<>(map, headers);
//        String data = restTemplate.postForObject("",request,String.class);
            JSONObject result = restTemplate.postForObject(SysConstant.NOTIC_SEND_OUTPIC_URL, request, JSONObject.class);
            if (result != null){
                if (result.getBoolean("success")){
                    if (result.get("result") != null) {
                        log.info("Web端下发图形成功：{}", JSON.toJSONString(result.get("result")));
                    }
                    return new ResponseResult(true,"Web端下发图形成功",null);
                }else {
                    log.warn("Web端下发图形失败：{}",result.get("msg") ==null ? "": result.getString("msg"));
                }
            }
            return new ResponseResult(false,"Web端下发图形失败",null);
        } catch (Exception e) {
            log.error("===============web端下发工单失败===============",e);
            return new ResponseResult(false,"Web端下发图形失败",null);
        }
    }
}
